#include "Sol9Math.h"
#include "Sol9Util.h"
#include "radian.h"
#include "degree.h"

namespace sol9
{
namespace core
{

	/// constructors
	radian::radian()
		: r(0.0f)
	{
	}

	radian::radian(f32 radians)
		: r(radians)
	{
	}

	radian::radian(const radian& radians)
		: r(radians.r)
	{
	}

	radian::radian(const degree& degrees)
		: r(degrees.makeRadian())
	{
	}

	/// operators
	// -radian
	radian radian::operator-() const
	{
		return radian(-r);
	}

	// radian = value
	radian& radian::operator=(const f32& value)
	{
		r = value;
		return *this;
	}

	// radian = radian
	radian& radian::operator=(const radian& radians)
	{
		r = radians.r;
		return *this;
	}

	// radian = degree
	radian& radian::operator=(const degree& degrees)
	{
		r = degrees.makeRadian();
		return *this;
	}

	// radian + radian
	radian radian::operator+(const radian& radians) const
	{
		return radian(r + radians.r);
	}

	// radian + degree
	radian radian::operator+(const degree& degrees) const
	{
		return radian(r + degrees.makeRadian());
	}

	// radian += radian
	radian& radian::operator+=(const radian& radians)
	{
		r += radians.r;
		return *this;
	}

	// radian += degree
	radian& radian::operator+=(const degree& degrees)
	{
		r += degrees.makeRadian();
		return *this;
	}

	// radian - radian
	radian radian::operator-(const radian& radians) const
	{
		return radian(r - radians.r);
	}

	// radian - degree
	radian radian::operator-(const degree& degrees) const
	{
		return radian(r - degrees.makeRadian());
	}

	// radian -= radian
	radian& radian::operator-=(const radian& radians)
	{
		r -= radians.r;
		return *this;
	}

	// radian -= degree
	radian& radian::operator-=(const degree& degrees)
	{
		r -= degrees.makeRadian();
		return *this;
	}

	// radian * value
	radian radian::operator*(const f32& value) const
	{
		return radian(r * value);
	}

	// radian * radian
	radian radian::operator*(const radian& radians) const
	{
		return radian(r * radians.r);
	}

	// radian *= value
	radian& radian::operator*=(const f32& value)
	{
		r *= value;
		return *this;
	}

	// radian / value
	radian radian::operator/(const f32& value) const
	{
		if (core::isZero(value))
			return radian(r);

		return radian(r / value);
	}

	// radian /= value
	radian& radian::operator/=(const f32& value)
	{
		if (core::isZero(value))
			return *this;

		r /= value;
		return *this;
	}

	// radian == radian
	bool radian::operator==(const radian& radians) const
	{
		return core::equals(r, radians.r);
	}

	// radian < radian
	bool radian::operator<(const radian& radians) const
	{
		return r < radians.r;
	}

	// radian <= radian
	bool radian::operator<=(const radian& radians) const
	{
		return (r < radians.r) || (core::equals(r, radians.r));
	}

	// radian > radian
	bool radian::operator>(const radian& radians) const
	{
		return r > radians.r;
	}

	// radian >= radian
	bool radian::operator>=(const radian& radians) const
	{
		return (r > radians.r) || (core::equals(r, radians.r));
	}

	//// radian == degree
	//bool radian::operator==(const degree& degrees) const
	//{
	//	return core::equals(r, degrees.makeRadians());
	//}

	// radian != radian
	bool radian::operator!=(const radian& radians) const
	{
		return !core::equals(r, radians.r);
	}

	//// radian != degree
	//bool radian::operator!=(const degree& degrees) const
	//{
	//	return !core::equals(r, degrees.makeRadians());
	//}

	/// functions
	f32 radian::makeDegree() const
	{
		return core::rad2deg(r);
	}

} // namespace core
} // namespace sol9